/**
 * 
 */
package com.gragra.distances;
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
import it.unimi.dsi.fastutil.ints.Int2DoubleOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
/**
 * this class implements methods that can be used to calculate norms for vectors
 * @author Christoph Teichmann
 * created May 2, 2013 11:11:50 AM
 * @version 0.1
 */
public class DistanceTools
{
	/**
	 * can be used to cacultate the L2-Norm for the given map interpreted like a VectorStructure
	 * @param sums
	 * @return
	 */
	public static double getL2Norm(Int2ObjectMap<Int2DoubleOpenHashMap> sums)
	{
		double ret = 0.0;
		for(Int2DoubleOpenHashMap map : sums.values())
		{
			DoubleIterator di = map.values().iterator();
			while(di.hasNext())
			{
				double d = di.nextDouble();
				ret += d*d;
			}
		}
		return Math.sqrt(ret);
	}
	/**
	 * can be used to calculate the L2-Norm for the given vector
	 * @param values
	 * @return
	 */
	public static double getL2Norm(double[] values)
	{
		double ret = 0.0;
		for(double d : values)
		{ret += d*d;}
		return Math.sqrt(ret);
	}
	/**
	 * returns the P-Norm for the given vector
	 * @param values
	 * @param p
	 * @return
	 */
	public static double getPNorm(double[] values, double p)
	{
		double ret = 0.0;
		for(double d : values)
		{ret += Math.pow(Math.abs(d), p);}
		return Math.pow(ret, 1.0/p);
	}
	/**
	 * returns the P-Norm for the given data
	 * @param sums
	 * @param p
	 * @return
	 */
	public static double getPNorm(Int2ObjectMap<Int2DoubleOpenHashMap> sums, double p)
	{
		double ret = 0.0;
		for(Int2DoubleOpenHashMap map : sums.values())
		{
			DoubleIterator di = map.values().iterator();
			while(di.hasNext())
			{
				double d = di.nextDouble();
				ret += Math.pow(Math.abs(d), p);
			}
		}
		return Math.pow(ret, 1.0/p);
	}
}